/*
 * fixmath.h
 *
 * Copyright (c) 2010, Alan Green.
 * Contactable at <firstname>.<lastname>@gmail.com
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 	1.	Redistributions of source code must retain the above copyright
 * 		notice, this list of conditions and the following disclaimer.
 * 	2.	Redistributions in binary form must reproduce the above copyright
 * 		notice, this list of conditions and the following disclaimer in the
 * 		documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * ===============================================
 */

#ifndef FIXMATH_H_
#define FIXMATH_H_

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// Fixed is a signed 16 bit int, treated as a signed fixed point number with 15
// bits below the point. This allows it to represent values values in the range [-1, 1).
typedef int16_t Fixed;

// Builds the 16 bit representation of a floating point number
// As a macro to ensure heavy-lifting done at compile time
// FC = fixed, const
#define FC(e) ((Fixed) (e * 32768))

// An external zero - useful in tests
extern Fixed F0;

inline int nearly_equal(Fixed a, Fixed b) {
	int16_t diff = a - b;
	return diff > -3 && diff < 3;
}

// Multiply numbers, taking into account the fixed point
Fixed fix_mul(Fixed a, Fixed b);

// Trig functions.
// Remember SOHCAHTOA?
// These functions work in a fast but somewhat inaccurate manner, using only
// Opposite and Adjacent measurements

// Calculates the sine of an angle defined by adjacent and opposite lengths
Fixed fix_sin(Fixed adj, Fixed opp);

// Ditto for cos
inline Fixed fix_cos(Fixed adj, Fixed opp) { return fix_sin(opp, adj); }

#ifdef __cplusplus
}
#endif
#endif /* FIXMATH_H_ */
